/*
		ServEngine framework library
		A library to fast develop JEE online applications
	
		Copyright 2008 José Ignacio de Córdoba Álvaro

		Licensed under the Apache License, Version 2.0 (the "License");
		you may not use this file except in compliance with the License.
		You may obtain a copy of the License at

				http://www.apache.org/licenses/LICENSE-2.0

		Unless required by applicable law or agreed to in writing, software
		distributed under the License is distributed on an "AS IS" BASIS,
		WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
		See the License for the specific language governing permissions and
		limitations under the License.
	
		Jose Ignacio de Cordoba Alvaro
		http://ignacio.decordoba.com
*/

package com.servengine.tag;

import com.servengine.portal.Portal;

import java.util.ArrayList;
import java.util.Collection;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.ejb.Stateless;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless(name="TagManager")
public class TagManagerBean implements TagManagerLocal
{
	private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog( TagManagerBean.class.getName() );
	@PersistenceContext(unitName="mainPersistenceUnit")
	private EntityManager entityManager;

/*	public void ejbCreate() throws javax.ejb.CreateException
	{
	  try
	  {
	    javax.naming.Context initial = new javax.naming.InitialContext();
			totalTagCount = tagLocalHome.findAll().size();
			totalItemCount = taggedItemLocalHome.findAll().size();
			log.info("totalTagCount="+totalTagCount+",totalItemCount="+totalItemCount);
	  } catch (Exception e)
	  {
	    log.error(e.getMessage(), e);
	    throw new javax.ejb.CreateException("Can't locate EJBs: " + e.getMessage());
	  }
	}*/

 public List<TaggedItem> getTaggedItems(String portalid, String module, String itemType)
 {
	 Query query = entityManager.createNamedQuery("TaggedItem.findByModuleType");
	 query.setParameter("portalid",portalid);
	 query.setParameter("module",module);
	 query.setParameter("itemType",itemType);
	 return query.getResultList();
 }

	public List<TaggedItem> getTaggedItems(String portalid, String module, String itemType, String itemName)
	{
	  Query query = entityManager.createNamedQuery("TaggedItem.findByModuleTypeAndItemName");
	  query.setParameter("portalid",portalid);
	  query.setParameter("module",module);
	  query.setParameter("itemType",itemType);
	  query.setParameter("itemName",itemName);
	  return query.getResultList();
	}

	public List<TaggedItem> getTaggedItems(String portalid, String module, String itemType, Integer itemId)
	{
	  Query query = entityManager.createNamedQuery("TaggedItem.findByModuleTypeAndItemId");
	  query.setParameter("portalid",portalid);
	  query.setParameter("module",module);
	  query.setParameter("itemType",itemType);
	  query.setParameter("itemId",itemId);
	  return query.getResultList();
	}

	public void removeTaggedItems(String portalid, String moduleid, String itemType, String itemId)
	{
		Collection<TaggedItem> expurganda = new ArrayList<TaggedItem>();
		expurganda.addAll(getTaggedItems(portalid,moduleid,itemType,itemId));
		for (TaggedItem item: expurganda)
			entityManager.remove(item);
	}

	public void removeTaggedItems(String portalid, String moduleid, String itemType, Integer itemId)
	{
	  Collection<TaggedItem> expurganda = new ArrayList<TaggedItem>();
	  expurganda.addAll(getTaggedItems(portalid,moduleid,itemType,itemId));
	  for (TaggedItem item: expurganda)
	    entityManager.remove(item);
	}

	public TaggedItem createTaggedItem(Portal portal, String module, String itemType, Integer itemId, String body, String locale)
	{
	  if (body==null)
		{
			if (log.isDebugEnabled())
				log.debug("null tag. Returning null and not creating anything.");
			return null;
		}
		body=body.toLowerCase().trim();
		if (body.length()<2)
		{
		  if (log.isDebugEnabled())
		    log.debug("One char or empty tag. Returning null and not creating anything.");
			return null;
		}
		Tag tag=entityManager.find(Tag.class,body);
		if (tag==null)
		{
			tag = new Tag(body, locale);
			entityManager.persist(tag);
		}
		for (TaggedItem item: getTaggedItems(portal.getId(),module,itemType,itemId))
			if (item.getTag().getBody().equals(body))
				return item;
		TaggedItem taggedItem = new TaggedItem(portal,module,itemType,itemId,tag);
		entityManager.persist(taggedItem);
		return taggedItem;
	}

	public Collection<TaggedItem> findTaggedItems(String portalid, String module, String itemType, Tag tag)
	{
	  Query query = entityManager.createNamedQuery("TaggedItem.findByModuleTypeAndTag");
	  query.setParameter("portalid",portalid);
	  query.setParameter("module",module);
	  query.setParameter("itemType",itemType);
	  query.setParameter("tag",tag);
	  return query.getResultList();
	}

	public Collection<TaggedItem> findTaggedItems(String portalid, String module, String itemType, String tagBody)
	{
		Tag tag = entityManager.find(Tag.class,tagBody);
		Query query = entityManager.createNamedQuery("TaggedItem.findByModuleTypeAndTag");
		query.setParameter("portalid",portalid);
		query.setParameter("module",module);
		query.setParameter("itemType",itemType);
		query.setParameter("tag",tag);
		return query.getResultList();
	}

	public Set<Tag> getTags(String portalid, String module, String itemType, Integer itemId)
	{
		Collection<TaggedItem> taggedItems = itemId == null ?
			getTaggedItems(portalid,module,itemType)
			:getTaggedItems(portalid,module,itemType,itemId);
	  Set<Tag> tags = new HashSet<Tag>();
	  for (TaggedItem taggedItem: taggedItems)
	    tags.add(taggedItem.getTag());
	  return tags;
	}

	public void removeTaggedItem(String portalid, Integer itemId, Integer id)
	{
		TaggedItem item = entityManager.find(TaggedItem.class,id);
		if (!item.getPortal().getId().equals(portalid) || !item.getItemId().equals(itemId))
			throw new IllegalArgumentException();
		entityManager.remove(item);
	}
	
	public  Tag getTag(String body, String locale, boolean create)
	{
		Tag tag = entityManager.find(Tag.class,body);
		if (tag==null && create)
		{
			tag = new Tag(body,locale);
			entityManager.persist(tag);
			entityManager.flush();//Si no, dentro de una transacción casca
		}
		return tag;
	}
}
